#include	"Vector2f.h"
#include	"Vector2i.h"
#include	<cmath>

const float Vector2f::EPSILON = 0.0001f;

Vector2f::Vector2f()
{
}

Vector2f::Vector2f(float x, float y)
{
	Set(x, y);
}

Vector2f::Vector2f(int x, int y)
{
	Set(x, y);
}

Vector2f::Vector2f(const Vector2f & vec)
{
	Set(vec);
}

Vector2f::Vector2f(const Vector2i & vec)
{
	Set(vec);
}

Vector2f::Vector2f(const float * arr)
{
	Set(arr);
}

Vector2f::Vector2f(const int * arr)
{
	Set(arr);
}

Vector2f::~Vector2f()
{
}

void Vector2f::Set(float x, float y)
{
	m_data[0] = x;
	m_data[1] = y;
}

void Vector2f::Set(int x, int y)
{
	m_data[0] = float(x);
	m_data[1] = float(y);
}

void Vector2f::Set(const float * arr)
{
	m_data[0] = arr[0];
	m_data[1] = arr[1];
}

void Vector2f::Set(const int * arr)
{
	m_data[0] = float(arr[0]);
	m_data[1] = float(arr[1]);
}

Vector2f::operator const float*() const
{
	return m_data;
}

Vector2f::operator float*()
{
	return m_data;
}

const Vector2f & Vector2f::operator+() const
{
	return *this;
}

Vector2f & Vector2f::operator+()
{
	return *this;
}

Vector2f Vector2f::operator-() const
{
	return Vector2f(-m_data[0], -m_data[1]);
}

Vector2f & Vector2f::operator=(const Vector2f & vec)
{
	Set(vec);
	return *this;
}

Vector2f & Vector2f::operator=(const Vector2i & vec)
{
	Set(vec);
	return *this;
}

Vector2f & Vector2f::operator+=(const Vector2f & vec)
{
	Set(m_data[0] + vec[0], m_data[1] + vec[1]);
	return *this;
}

Vector2f & Vector2f::operator+=(const Vector2i & vec)
{
	Set(m_data[0] + vec[0], m_data[1] + vec[1]);
	return *this;
}

Vector2f & Vector2f::operator-=(const Vector2f & vec)
{
	Set(m_data[0] - vec[0], m_data[1] - vec[1]);
	return *this;
}

Vector2f & Vector2f::operator-=(const Vector2i & vec)
{
	Set(m_data[0] - vec[0], m_data[1] - vec[1]);
	return *this;
}

Vector2f & Vector2f::operator*=(float num)
{
	Set(m_data[0] * num, m_data[1] * num);
	return *this;
}

Vector2f & Vector2f::operator*=(int num)
{
	Set(m_data[0] * num, m_data[1] * num);
	return *this;
}

Vector2f & Vector2f::operator/=(float num)
{
	Set(m_data[0] / num, m_data[1] / num);
	return *this;
}

Vector2f & Vector2f::operator/=(int num)
{
	Set(m_data[0] / num, m_data[1] / num);
	return *this;
}

Vector2f Vector2f::operator+(const Vector2f & vec) const
{
	return Vector2f(m_data[0] + vec[0], m_data[1] + vec[1]);
}

Vector2f Vector2f::operator+(const Vector2i & vec) const
{
	return Vector2f(m_data[0] + vec[0], m_data[1] + vec[1]);
}

Vector2f Vector2f::operator-(const Vector2f & vec) const
{
	return Vector2f(m_data[0] - vec[0], m_data[1] - vec[1]);
}

Vector2f Vector2f::operator-(const Vector2i & vec) const
{
	return Vector2f(m_data[0] - vec[0], m_data[1] - vec[1]);
}

Vector2f Vector2f::operator*(float num) const
{
	return Vector2f(m_data[0] * num, m_data[1] * num);
}

Vector2f Vector2f::operator*(int num) const
{
	return Vector2f(m_data[0] * num, m_data[1] * num);
}

Vector2f Vector2f::operator/(float num) const
{
	return Vector2f(m_data[0] / num, m_data[1] / num);
}

Vector2f Vector2f::operator/(int num) const
{
	return Vector2f(m_data[0] / num, m_data[1] / num);
}

Vector2f operator*(float num, const Vector2f & vec)
{
	return Vector2f(vec[0] * num, vec[1] * num);
}

Vector2f operator*(int num, const Vector2f & vec)
{
	return Vector2f(vec[0] * num, vec[1] * num);
}

bool Vector2f::operator==(const Vector2f & vec) const
{
	return ((vec[0] - Vector2f::EPSILON) <= m_data[0]) && (m_data[0] <= (vec[0] + Vector2f::EPSILON))
		&& ((vec[1] - Vector2f::EPSILON) <= m_data[1]) && (m_data[1] <= (vec[1] + Vector2f::EPSILON));
}

bool Vector2f::operator==(const Vector2i & vec) const
{
	return ((vec[0] - Vector2f::EPSILON) <= m_data[0]) && (m_data[0] <= (vec[0] + Vector2f::EPSILON))
		&& ((vec[1] - Vector2f::EPSILON) <= m_data[1]) && (m_data[1] <= (vec[1] + Vector2f::EPSILON));
}

bool operator==(const Vector2i & veci, const Vector2f & vecf)
{
	return ((veci[0] - Vector2f::EPSILON) <= vecf[0]) && (vecf[0] <= (veci[0] + Vector2f::EPSILON))
		&& ((veci[1] - Vector2f::EPSILON) <= vecf[1]) && (vecf[1] <= (veci[1] + Vector2f::EPSILON));
}

bool Vector2f::operator!=(const Vector2f & vec) const
{
	return ((vec[0] - Vector2f::EPSILON) > m_data[0]) || (m_data[0] > (vec[0] + Vector2f::EPSILON))
		|| ((vec[1] - Vector2f::EPSILON) > m_data[1]) || (m_data[1] > (vec[1] + Vector2f::EPSILON));
}

bool Vector2f::operator!=(const Vector2i & vec) const
{
	return ((vec[0] - Vector2f::EPSILON) > m_data[0]) || (m_data[0] > (vec[0] + Vector2f::EPSILON))
		|| ((vec[1] - Vector2f::EPSILON) > m_data[1]) || (m_data[1] > (vec[1] + Vector2f::EPSILON));
}

bool operator!=(const Vector2i & veci, const Vector2f & vecf)
{
	return ((veci[0] - Vector2f::EPSILON) > vecf[0]) || (vecf[0] > (veci[0] + Vector2f::EPSILON))
		|| ((veci[1] - Vector2f::EPSILON) > vecf[1]) || (vecf[1] > (veci[1] + Vector2f::EPSILON));
}

double Vector2f::LengthSquare() const
{
	return double(m_data[0] * m_data[0]) + double(m_data[1] * m_data[1]);
}

double Vector2f::Length() const
{
	return std::sqrt(double(m_data[0] * m_data[0]) + double(m_data[1] * m_data[1]));
}

void Vector2f::Normalize()
{
	double inverse_length = 1 / Length();
	Set(float(m_data[0] * inverse_length), float(m_data[1] * inverse_length));
}

Vector2f Vector2f::Normal() const
{
	double inverse_length = 1 / Length();
	return Vector2f(float(m_data[0] * inverse_length), float(m_data[1] * inverse_length));
}

